#include <string.h>
#include <stdlib.h>

typedef unsigned char boolean;
#define false 0
#define true 1
#define MAX 256

class Exception{


public:
	 char error[256];
	 Exception(char* a){

	 	strcpy(error,a);
	 	printError();
	 }

	 void printError(){

	 	printf("sorry runtime have a big problem error-----------------------------\n");
	 	printf("Reason:   %s\n",error);
	 	exit(-1);
	 }



};

/////////
class Object{

public:
  char name[11];
  int  version;
  Object *self;
  char tag[10];

public:

	  Object(){

	  	version = 1 ;
	  	self = this;
	  	sprintf(name,"%X",(int)(Object*)this);
	  	strcpy(tag,"Object");
	  }

	

	///////////////////////
	 int hashCode(){


		return (int)&version;//&this;
	}

	 virtual char* toString(){

			 
			static char p[256]={0};
			sprintf(p,"Obj@%x",hashCode());
			
			
			return p;
	}

	boolean equals(Object obj){

		return hashCode() == obj.hashCode();
	}
	char* getType(){

 	return tag;
 	}


////////////////////
	boolean operator == (Object obj){

			if(hashCode()==obj.hashCode()){

				return true;
			}else{

				return false;
			}

	}

	


};

 class  String :public  Object{

 public :

  char mString[MAX];
  char  tag[10];
  int  count;

  ////
  String(){


  }
  String(char* str){
    //printf("caonima");
  	strcpy(mString,str);
  	strcpy(tag,"String");
  	count = strlen(mString);
  }


public:


	 operator = (char* str){

			
	 		strcpy(mString,str);
	 		count = strlen(mString);
	}
   char* operator + (String str){
    //strcat(mString,(const)str.toString);
    //kao if not + char* default it auto trance to String  class to add myGod!!
    char ret[MAX]={0};
    char* strPoint = str.toString();
    strcat(ret,mString);
    strcat(ret,strPoint);
    

    return ret;
   }
  char* operator + (char* point){ //it must have otherwise it will use up operator to work
    
      char ret[MAX]={0};//ok it must be init
      strcat(ret,mString);
      strcat(ret,point);

      return ret;

   }

////////////////
	 char* toString(){


		return mString;
	} // the duotai must use father class point to sublcass

 char* getType(){

 	return tag;
 }
int length(){

	return count;
}
   String toLowerCase(){

   		int len=strlen(mString);
   		char temp[256]={0};

   		for(int i=0; i < len; i++){

   			if(mString[i] >= 65 && mString[i] <= 90){

   				temp[i] = mString[i]+32;
   			}else{

   				temp[i] = mString[i];
   			}
   		}
   		//temp[i]='\0';  must first init or  no init but last give a \0;

   		return   String(temp);

   }

   char charAt(int index){

   	  if(index < count){

   	  	return mString[index];
   	  }
   	  Exception("array index out of bound ");
   	  return -1;
   }

   boolean equals(char* string0){

    String anoString(string0);
    return  equals(anoString);

   }

   boolean equals( String anoString){


   		
     
   		int n = count;
   		if(n == anoString.length() ){

   			int i=0;
   			while(n-- != 0){

   				if(charAt(i) != anoString.charAt(i)){

   					return false;
   				}
   				i++;
   			}

   			return true;

   		}

   		return false;

   }
   void print(){

    printf("%s\n",mString);
   }

   boolean isEmpty(){

    return count == 0;
   }
    String subString(int beginIndex){

        return subString(beginIndex,count);

    }

    String subString(int start,int endIndex){
          
          if(start < 0){

            new Exception("the string start little zero");
          }

          int subLen=endIndex-start;
          if(endIndex > count || subLen < 0){

            new Exception("the string long have out of Bounds");
          }

          char retStr[256]={0};
          if((start == 0) && (endIndex == count)){

            return String(mString);
          }
          for(int i=start,j=0;i <endIndex;i++,j++){

            retStr[j]=mString[i];
          }

          return String(retStr);


   }

  static int indexOf(String source,String target,int fromIndex){

      if(fromIndex >= source.length() || fromIndex <0 ||target.count == 0){

        return -1;
      }
       char  first = target.charAt(0);
       int max =(source.length()-target.length());
       for(int i= fromIndex; i <= max; i++){

          if(source.charAt(i) != first){

            while(++i <= max && source.charAt(i) != first);
          }

          if(i <= max){

              int j = i+1;
              int  end =j +target.length() -1;

              for(int k=1; j< end && source.charAt(j) == target.charAt(k); j++,k++);

              if(j == end){

                return i;
              }
          }
       }


       return -1;
  }
 
}; /////end  class
//////////////
////////////////////////

class StringBuilder :public Object{

public:
  char value[MAX];
  int index;


  StringBuilder(){

    for(int i=0; i<MAX;i++){

      value[i] = 0;
    }
    index = 0;
  }

 void append(char* str){

   int  n = strlen(str);
   for(int i=0; i< n;i++){

      value[index++]=*str++;
   }
 }
 void append(char c){

    value[index++]=c;
    
 }
 char* toString(){

  return value;
 }


};



//////class ArrayList;
#define DEFAULT_CAPACITY 20
class ArrayList:public Object{

public:

  int count;

  String elementData[DEFAULT_CAPACITY];


  ArrayList(){

    count=0;
  }

  void add(String str){

    
    elementData[count++] = str;


  }

  void add(char* str){

      add(String(str));
  }
 
  int size(){

    return count;
  }

  String get(int index){

    if(index < 0 || index >= count){

      new Exception("sorry index is out of bound");
    }

    return  elementData[index];
  }

  void clear(){

    for(int i=0; i < count;i++ ){

      elementData[i]="";
    }
    count =0;
  }






};